package apof.dao
{
	import flash.data.SQLStatement;
	import apof.model.*;
	import apof.util.Enumerater;
	import apof.dao.datapool.DataPool;
	import flash.utils.Dictionary;
	
	public class Dao
	{
		public static var dp:DataPool=new DataPool();
		
		private static var dataSource:DataSource=new DataSource();
			
		private static var checkRecord:Dictionary=new Dictionary();	
			
		private static function check(classInfo:Object):void {
			if(checkRecord[classInfo])return;
			checkRecord[classInfo]=true;
			createTable(classInfo);
		}

		private static function createTable(classInfo:Object):void {
			var stm:SQLStatement=new SQLStatement();
			var pt:Object=classInfo;
			var sql:String;
			sql="CREATE TABLE IF NOT EXISTS :classname (\n"+
				" :columDefs , \n"+
				"PRIMARY KEY ( :pklist )\n"+
				")";
			sql=sql.replace(/:classname/,pt.classname).
					replace(/:columDefs/,Enumerater.enumerate2Arrays(pt.fields,pt.fieldTypes)).
					replace(/:pklist/,pt.primaryKey);
			stm.text=sql;
			dataSource.excute(stm);
		}
			
		public static function create(target:ApofModel):void{
			check(target.classInfo);
			var stm:SQLStatement=new SQLStatement();
			var pt:Object=target.classInfo;
			var sql:String;
			sql="INSERT INTO :classname \n"+
				"( :fields ) \n"+
				"values ( :values )";
			sql=sql.replace(/:classname/,pt.classname).
					replace(/:fields/,Enumerater.enumerateArray(pt.fields)).
					replace(/:values/,Enumerater.repeat("?",pt.fields.length));
			stm.text=sql;
			for(var i:int=0;i<pt.fields.length;i++) {
				stm.parameters[i+1]=target[pt.fields[i]];
			}
			dataSource.excute(stm);
		}
		
		public static function update(target:ApofModel):void{
			check(target.classInfo);
			var stm:SQLStatement=new SQLStatement();
			var pt:Object=target.classInfo;
			var sql:String;
			sql="UPDATE :classname SET  \n"+
				" :properties = ? \n"+
				"WHERE ( :pk = :value )";
			sql=sql.replace(/:classname/,pt.classname).
					replace(/:properties/,Enumerater.enumerateArray(pt.fields," = ? ,\n")).
					replace(/:pk/,pt.primaryKey).
					replace(/:value/,target[pt.primaryKey]);;
			stm.text=sql;
			for(var i:int=0;i<pt.fields.length;i++) {
				stm.parameters[i+1]=target[pt.fields[i]];
			}
			dataSource.excute(stm);
		}
		
		public static function remove1(target:ApofModel):void{
			check(target.classInfo);
			var stm:SQLStatement=new SQLStatement();
			var pt:Object=target.classInfo;
			var sql:String;
//			sql="DELETE FROM :classname \n "+
//				"WHERE ( :condition = ? )";
//			sql=sql.replace(/:classname/,pt.classname).
//					replace(/:condition/,Enumerater.enumerateArray([pt.primaryKey]," = ? AND "));
//			stm.text=sql;
//			for(var i:int=0;i<[pt.primaryKey].length;i++) 
//				stm.parameters[i+1]=target[[pt.primaryKey][i]];
//			dataSource.excute(stm);
			sql="DELETE FROM :classname \n "+
				"WHERE ( :pk = :value )";
			sql=sql.replace(/:classname/,pt.classname).
					replace(/:pk/,pt.primaryKey).
					replace(/:value/,target[pt.primaryKey]);
			stm.text=sql;
			dataSource.excute(stm);
		}
		public static function remove2(clazz:Class , id:int):void{
			check(clazz.classInfo);
			var stm:SQLStatement=new SQLStatement();
			var pt:Object=clazz.classInfo;
			var sql:String;
			sql="DELETE FROM :classname \n "+
				"WHERE ( :pk = :value )";
			sql=sql.replace(/:classname/,pt.classname).
					replace(/:pk/,pt.primaryKey).
					replace(/:value/,id.toString());
			stm.text=sql;
			dataSource.excute(stm);
		}
	
		public static function retrive1(clazz:Class , id:int , callback:Function):void{
			var conditionMap:Object=new Object;
			conditionMap[clazz.classInfo.primaryKey[0]]=id;
			retrive3(clazz,conditionMap,callback);
		}
		public static function retrive2(clazz:Class , key:String , value:Object , callback:Function):void{
			var conditionMap:Object={key:value};
			retrive3(clazz,conditionMap,callback);
		}
		public static function retrive3(clazz:Class , conditionsMap:Object , callback:Function):void{
			retrive4(clazz,conditionsMap,null,callback);
		}
		public static function retrive4(clazz:Class , conditionsMap:Object , constraintMap:Object , callback:Function):void{
			check(clazz.classInfo)
			var stm:SQLStatement=new SQLStatement();
			var pt:Object=clazz.classInfo;
			var sql:String;
			sql="SELECT * FROM :classname \n"+
				":wherecourse \n"+
				":ordercourse \n"+
				":limitcourse";
				var where:String="";
				if(conditionsMap!=null) {
					where="WHERE :conditions";
					where=where.replace(/:conditions/,Enumerater.enumerateKeys(conditionsMap," = ?\n\t"));
				}
				var order:String="";
				if(constraintMap!=null && constraintMap["order"]!=null) 
					order="ORDER BY "+constraintMap["order"];
				var limit:String="";
				if(constraintMap!=null && constraintMap["size"]!=null)
					limit="LIMIT "+constraintMap["size"];
			sql=sql.replace(/:classname/,pt.classname).
					replace(/:wherecourse/,where).
					replace(/:ordercourse/,order).
					replace(/:limitcourse/,limit);
			stm.text=sql;
			var i:int=0;
			for(var key:String in conditionsMap) {
				stm.parameters[++i]=conditionsMap[key];
			}
			stm.itemClass=clazz;
			dataSource.excute(stm,callback);
		}
		
				
	}
}